import { Enum, director } from "cc";
import { EventEnum, MJRemoveWay, MJStyleEnum, MJTeam, MJType, MJValue, getMJType } from "./Enum";
import { ArrayUtil } from "./ArrayUtil";

export default class GameController {

    private static _instance: GameController;

    public static getInstance(): GameController {
        if (!this._instance) {
            this._instance = new GameController();
        }
        return this._instance;
    }

    private mjList = [];
    private hands = [];
    private deck = [];

    private MJRemember = [];

    private _score = 0;

    public initGame() {
        for (let i = 0; i < MJValue.COUNT; i++) {
            this.mjList.push(i);
            this.mjList.push(i);
            this.mjList.push(i);
            this.mjList.push(i);
        }

        console.log(this.mjList);

        // 洗牌
        this.mjList = ArrayUtil.randomCount(this.mjList, MJValue.COUNT * 4);
        console.log(this.mjList);

        // 发牌
        for (let i = 0; i < 8; i++) {
            this.deck.push([]);
            this.hands.push(this.mjList.shift());
            for (let j = 0; j < 16; j++) {
                this.deck[i].push(this.mjList.shift());
            }
        }
        this.sortHand();

        director.emit(EventEnum.EVENT_SHUFFLE);
    }

    private sortHand() {
        this.hands = this.hands.sort((a, b) => a - b);
    }

    public get Hand() {
        return this.hands;
    }

    public getDeck(index) {
        console.log(this.deck[index]);
        return ArrayUtil.copy(this.deck[index]);
    }

    public getMjInDeck(DeckIndex, mjIndex) {
        if (mjIndex > this.deck[DeckIndex].length - 1) {
            return null;
        }
        return this.deck[DeckIndex][mjIndex];
    }

    public inHand(deck) {
        if (this.hands.length >= 14) {
            return;
        }
        let mj = this.deck[deck].shift();
        this.hands.push(mj);
        director.emit(EventEnum.EVENT_INHAND, mj);
        director.emit(EventEnum.EVENT_DECKPOP, deck, mj);

        this.sortHand();

        console.log(this.hands);

        this.getChiList();
        this.getPengList();
        this.getGangList();
        this.checkHu(this.hands);
        if (this.checkSameColor()) {

        }
    }

    public getChiList() {
        let chiList = [];
        let handsUnique = ArrayUtil.unique(this.hands);
        if (handsUnique.length < 3) {
            return;
        }
        for (let i = 0; i < handsUnique.length - 2; i++) {
            if (getMJType(handsUnique[i]) != MJType.OTHER) {
                if (handsUnique[i] + 1 === handsUnique[i + 1] && handsUnique[i] + 2 === handsUnique[i + 2]) {
                    if (getMJType(handsUnique[i]) === getMJType(handsUnique[i + 1]) && getMJType(handsUnique[i]) === getMJType(handsUnique[i + 2])) {
                        chiList.push(handsUnique[i]);
                    }
                }
            }
        }
        return chiList;
    }

    private getPairList() {
        let pairList = [];
        for (let i = 0; i < this.hands.length - 1; i++) {
            if (this.hands[i] === this.hands[i + 1]) {
                pairList.push(this.hands[i]);
            }
        }
        return pairList;
    }

    private getPengList() {
        let pengList = [];
        for (let i = 0; i < this.hands.length - 2; i++) {
            if (this.hands[i] === this.hands[i + 1] && this.hands[i] === this.hands[i + 2]) {
                pengList.push(this.hands[i]);
            }
        }
        return pengList;
    }

    private getGangList() {
        let gangList = [];
        for (let i = 0; i < this.hands.length - 3; i++) {
            if (this.hands[i] === this.hands[i + 1] && this.hands[i] === this.hands[i + 2]
                && this.hands[i] === this.hands[i + 3]) {
                gangList.push(this.hands[i]);
            }
        }
        return gangList;
    }

    private checkSevenPair() {
        let pairList = this.getPairList();
        let pengList = this.getPengList();
        let gangList = this.getGangList();
        if (pairList.length < 7) {
            return false;
        }
        if (pairList.length == 7 && pengList.length == 0 && gangList.length == 0) {
            return true;
        } else {
            if (pairList.length - gangList.length == 7) {
                return true;
            }
            return false;
        }
    }

    private checkLong() {

    }

    private checkSameColor() {
        if (this.hands.length != 14) {

        }
        let color = getMJType(this.hands[0])
        let sameColor = true;
        for (let i = 0; i < this.hands.length; i++) {
            if (getMJType(this.hands[i]) != color) {
                sameColor = false;
                break;
            }
        }
        return sameColor && this.checkHu(this.hands);
    }

    private checkHu(list, jiang = false) {
        this.checkSevenPair();
        this.checkLong();
        this.checkSameColor();
        if (list.length == 0 && jiang) {
            return true;
        }
        let rst = false;
        let temp = [].concat(list);

        if (!jiang && this.getPairList().indexOf(this.hands[0]) != -1) {

            temp.shift();
            temp.shift();
            rst = this.checkHu(temp, true);
        }
        if (!rst && list.length >= 3 && this.getPengList().indexOf(0) != -1) {
            temp.shift();
            temp.shift();
            temp.shift();
            rst = this.checkHu(temp, jiang);
        }
        if (!rst && list.length >= 4 && this.getGangList().indexOf(0) != -1) {
            temp.shift();
            temp.shift();
            temp.shift();
            temp.shift();
            rst = this.checkHu(temp, jiang);
        }
        if (!rst && list.length >= 3 && this.getChiList().indexOf(0) != -1) {
            temp.shift();
            temp.shift();
            temp.shift();
            rst = this.checkHu(temp, jiang);
        }
        console.log(list);
        console.log(temp);
        return rst;
    }


    public onChi(index) {
        let chiList = this.getChiList();
        if (chiList.length == 0) {
            return;
        }

        let mjValue = chiList[index];

        console.log(mjValue);

        let add = 2;
        while (add >= 0) {
            let index = this.hands.indexOf(mjValue + add);
            this.hands.splice(index, 1);
            add--;
        }
        console.log(this.hands);

        this.pushToLibary({ mj: [mjValue, mjValue + 1, mjValue + 2], way: MJRemoveWay.CHI });
        this.addScore(100);
        director.emit(EventEnum.EVENT_CHI, mjValue);
    }

    public onPeng() {
        let pengList = this.getPengList();
        if (pengList.length == 0) {
            director.emit(EventEnum.EVENT_PENG_FAIL)
            return;
        }

        let mjValue = pengList[0];
        console.log(mjValue);

        for (let i = 0; i < this.hands.length; i++) {
            if (this.hands[i] === mjValue) {
                this.hands.splice(i, 3);
                break;
            }
        }
        console.log(this.hands);

        this.pushToLibary({ mj: [mjValue, mjValue, mjValue], way: MJRemoveWay.PENG });
        this.addScore(200);
        director.emit(EventEnum.EVENT_PENG, mjValue)
    }

    public onGang() {
        let gangList = this.getGangList();
        if (gangList.length == 0) {
            return;
        }

        let mjValue = gangList[0];

        for (let i = 0; i < this.hands.length; i++) {
            if (this.hands[i] === mjValue) {
                this.hands.splice(i, 4);
                break;
            }
        }

        this.pushToLibary({ mj: [mjValue, mjValue, mjValue, mjValue], way: MJRemoveWay.GANG });
        this.addScore(500);
        director.emit(EventEnum.EVENT_GANG, mjValue)
    }

    public onSevenPair() {
        let pairs = this.getPairList();
        if (this.checkSevenPair()) {

            this.handsClear();
            director.emit(EventEnum.EVENT_SEVEN_PAIR);

        }
    }

    /**
     * 一条龙
     * @returns 
     */
    public onLong() {
        let chiList = this.getChiList();
        if (chiList.length < 7) {
            return;
        } else {
            let count = 0
            for (let i = 0; i < 9; i++) {
                if (chiList.indexOf(MJValue.I1 + i) == -1) {
                    break;
                }
                count++
            }
            if (count == 9) {
                //条子一条龙
                return;
            }
            count = 0
            for (let i = 0; i < 9; i++) {
                if (chiList.indexOf(MJValue.O1 + i) == -1) {
                    break;
                }
            }
            if (count == 9) {
                //饼子一条龙
                return;
            }
            count = 0;
            for (let i = 0; i < 9; i++) {
                if (chiList.indexOf(MJValue.P1 + i) == -1) {
                    break;
                }
            }

            if (count == 9) {
                //万子一条龙
                return;
            }
        }

    }

    public onSameColor() {

    }

    public onHu() {
        this.checkHu(this.hands);
    }


    public handsClear() {
        this.hands = [];
    }

    public pushToLibary(mjTeam: MJTeam) {
        this.MJRemember.push(mjTeam);
    }

    private addScore(value) {

        this._score += value;
        director.emit(EventEnum.SCORE_UPDATE);
    }

    public get Score() {
        return this._score;
    }

}